#ifndef CHATSERVICE_H
#define CHATSERVICE_H

#include <unordered_map>
#include <functional>
#include <mutex>
#include <vector>
#include "json.hpp"
#include "UserModel.hpp"
#include "OfflineMessageModel.hpp"
#include "FriendModel.hpp"
#include "muduo/net/TcpConnection.h"
#include "GroupModel.hpp"
// #include "redis_topic.hpp"
#include "kafka.hpp"
#include "RedisCache.hpp"

using namespace std;
using namespace muduo;
using namespace muduo::net;

using json = nlohmann::json;
using MsgHandler = function<void(const TcpConnectionPtr &, json &, Timestamp time)>;


class ChatService{
public:
    // 获取单例对象
    static ChatService& instance();
    
    //登录
    void login(const TcpConnectionPtr& conn, json& js, Timestamp time);
    
    //注册
    void regist(const TcpConnectionPtr& conn, json& js, Timestamp time);
    
    //一对一聊天
    void oneChat(const TcpConnectionPtr& conn, json& js, Timestamp time);

    //异常退出
    void client_close_exception(const TcpConnectionPtr& conn);

    //添加好友
    bool addFriend(const TcpConnectionPtr &conn, json &js, Timestamp time);
    
    // 创建群组
    bool create_group(const TcpConnectionPtr &conn, json &js, Timestamp time);

    //添加群成员
    bool add_group(const TcpConnectionPtr &conn, json &js, Timestamp time);

    //群组聊天
    void group_chat(const TcpConnectionPtr& conn, json& js, Timestamp time);

    //服务主动关闭，全部下线
    void reset();

    //注销
    void logout(const TcpConnectionPtr& conn, json& js, Timestamp time);

    //从map里获取回调函数
    MsgHandler get_Handler(int msgid);

    //redis_topic 消息队列,用kafka后不用
    // void redis_subscribe_message_handler(int channel, string message);

    //kafka 消息队列
    void kafka_subscribe_message_handler(int topic, string message);

    //Redis缓存：
private:
    //注册消息以及对应的回调操作
    ChatService();

    bool isUserOnline(int user_id);

    void cacheOfflineMessage(int user_id, const string& message);

    vector<string> getOfflineMessages(int user_id);

    vector<User> getFriendsWithCache(int user_id);
private:
    //存储事件触发的回调函数
    unordered_map<int, MsgHandler> msg_handler_map_;
    
    //存储在线用户的连接情况，便于服务器给用户发消息，注意线程安全
    unordered_map<int, TcpConnectionPtr> user_conn_map_;
    mutex conn_mutex_;
    
    //redis 操作对象
    // Redis redis_;
    //kafka_
    Kafka kafka_;
    // Redis客户端(缓存)
    RedisCache redis_cache_; 

    UserModel user_model_;
    OfflineMessageModel offline_message_model_;
    FriendModel friend_model_;

    GroupModel group_model_;
};
#endif // !CHATSERVICE_H